package com.nuanshui.heatedloan.extension.jpasearch;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;

/**
 * 简单条件表达式
 * 
 * @author lee
 * 
 */
public class SimpleExpression implements Criterion {

	private final String fieldName; // 属性名
	private final Object value; // 对应值
	private final Operator operator; // 计算符
	private boolean isJoin = false;

	protected SimpleExpression(final String fieldName, final Object value,
			final Operator operator, final boolean isJoin) {
		this.fieldName = fieldName;
		this.value = value;
		this.operator = operator;
		this.isJoin = isJoin;
	}

	protected SimpleExpression(final String fieldName, final Object value,
			final Operator operator) {
		this.fieldName = fieldName;
		this.value = value;
		this.operator = operator;
	}

	public String getFieldName() {
		return fieldName;
	}

	public Object getValue() {
		return value;
	}

	public Operator getOperator() {
		return operator;
	}

	/**
	 * 组装成查询条件的方法
	 */
	@Override
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Predicate toPredicate(final Root<?> root,
			final CriteriaQuery<?> query, final CriteriaBuilder builder) {
		Path expression = null;
		if (fieldName.contains(".")) {
			String[] names = StringUtils.split(fieldName, ".");
			if (isJoin) {
				Join join = root.join(names[0]);
				expression = join.get(names[1]);
				for (int i = 2; i < names.length; i++) {
					expression = expression.get(names[i]);
				}
			} else {
				expression = root.get(names[0]);
				for (int i = 1; i < names.length; i++) {
					expression = expression.get(names[i]);
				}
			}

		} else {
			expression = root.get(fieldName);
		}
		switch (operator) {
		case EQ:
			return builder.equal(expression, value);
		case NE:
			return builder.notEqual(expression, value);
		case LIKE:
			return builder.like(expression, "%" + value + "%");
		case LT:
			return builder.lessThan(expression, (Comparable) value);
		case GT:
			return builder.greaterThan(expression, (Comparable) value);
		case LTE:
			return builder.lessThanOrEqualTo(expression, (Comparable) value);
		case GTE:
			return builder.greaterThanOrEqualTo(expression, (Comparable) value);
		case IN:
			return builder.in(null);
		default:
			return null;
		}
	}

}